#include "gtkplugprivate.h"
#include "x11/gdkx.h"
+#include <X11/Xatom.h>
#include "gtkxembed.h"
#include "gtkalias.h"
return return_val;
}
+
+void
+_gtk_plug_windowing_publish_natural_size (GtkPlug *plug,
+ GtkRequisition *requisition)
+{
+ GtkWidget *widget = GTK_WIDGET (plug);
+ GdkDisplay *display;
+ GdkWindow *window;
+ gint32 data[2];
+ Atom property;
+
+ gtk_widget_realize (widget);
+
+ window = GTK_WIDGET (plug)->window;
+ display = gdk_drawable_get_display (window);
+ property = gdk_x11_get_xatom_by_name_for_display (display, "_GTK_NATURAL_SIZE");
+
+ data[0] = requisition->width;
+ data[1] = requisition->height;
+
+ XChangeProperty (GDK_DISPLAY_XDISPLAY (display),
+ GDK_WINDOW_XWINDOW (window), property,
+ XA_CARDINAL, 32, PropModeReplace,
+ (unsigned char*)data, 2);
+}
+
#include "gtkmain.h"
#include "gtkmarshalers.h"
#include "gtkplug.h"
+#include "gtkextendedlayout.h"
#include "gtkintl.h"
#include "gtkprivate.h"
#include "gtkplugprivate.h"
gtk_plug_size_allocate (GtkWidget *widget,
GtkAllocation *allocation)
{
+ GtkBin *bin = GTK_BIN (widget);
+ GtkRequisition natural_size;
+
if (GTK_WIDGET_TOPLEVEL (widget))
GTK_WIDGET_CLASS (gtk_plug_parent_class)->size_allocate (widget, allocation);
else
}
}
+
+ gtk_extended_layout_get_desired_size (GTK_EXTENDED_LAYOUT (bin->child),
+ NULL, &natural_size);
+ _gtk_plug_windowing_publish_natural_size (GTK_PLUG (widget), &natural_size);
}
static gboolean
GdkEvent *event,
gpointer data);
+void _gtk_plug_windowing_publish_natural_size (GtkPlug *plug,
+ GtkRequisition *requisition);
+
#endif /* __GTK_PLUG_PRIVATE_H__ */
#include "gtkdnd.h"
#include "x11/gdkx.h"
+#include <X11/Xatom.h>
#ifdef HAVE_XFIXES
#include <X11/extensions/Xfixes.h>
gdk_error_trap_pop ();
}
+void
+_gtk_socket_windowing_get_natural_size (GtkSocket *socket)
+{
+ GtkSocketPrivate *priv;
+ GdkDisplay *display;
+
+ Atom property, type;
+ int format, status;
+
+ unsigned long nitems, bytes_after;
+ unsigned char *data;
+ gint32 *data_long;
+
+ priv = _gtk_socket_get_private (socket);
+
+ priv->natural_width = 1;
+ priv->natural_height = 1;
+
+ if (GTK_WIDGET_MAPPED (socket))
+ {
+ display = gdk_drawable_get_display (socket->plug_window);
+ property = gdk_x11_get_xatom_by_name_for_display (display, "_GTK_NATURAL_SIZE");
+
+ gdk_error_trap_push ();
+ status = XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display),
+ GDK_WINDOW_XWINDOW (socket->plug_window),
+ property, 0, 2, False, XA_CARDINAL,
+ &type, &format, &nitems, &bytes_after,
+ &data);
+ gdk_error_trap_pop ();
+
+ priv->have_natural_size = TRUE;
+
+ if (Success != status || !type)
+ return;
+
+ if (type != XA_CARDINAL)
+ {
+ g_warning ("_GTK_NATURAL_SIZE property has wrong type: %d\n", (int)type);
+ return;
+ }
+
+ if (nitems < 2)
+ {
+ g_warning ("_GTK_NATURAL_SIZE too short\n");
+ XFree (data);
+ return;
+ }
+
+ data_long = (gint32*) data;
+ priv->natural_width = MAX (1, data_long[0]);
+ priv->natural_height = MAX (1, data_long[1]);
+
+ XFree (data);
+ }
+}
+
void
_gtk_socket_windowing_send_key_event (GtkSocket *socket,
GdkEvent *gdk_event,
}
return_val = GDK_FILTER_REMOVE;
}
+ else if (xevent->xproperty.atom == gdk_x11_get_xatom_by_name_for_display (display, "_GTK_NATURAL_SIZE"))
+ {
+ _gtk_socket_windowing_get_natural_size (socket);
+ }
}
break;
case ReparentNotify:
#include "gtksocket.h"
#include "gtksocketprivate.h"
#include "gtkdnd.h"
+#include "gtkextendedlayout.h"
#include "gtkintl.h"
#include "gtkalias.h"
GtkCallback callback,
gpointer callback_data);
+static void gtk_socket_extended_layout_interface_init (GtkExtendedLayoutIface *iface);
/* Local data */
return G_TYPE_INSTANCE_GET_PRIVATE (socket, GTK_TYPE_SOCKET, GtkSocketPrivate);
}
-G_DEFINE_TYPE (GtkSocket, gtk_socket, GTK_TYPE_CONTAINER)
+G_DEFINE_TYPE_WITH_CODE (GtkSocket, gtk_socket, GTK_TYPE_CONTAINER,
+ G_IMPLEMENT_INTERFACE (GTK_TYPE_EXTENDED_LAYOUT,
+ gtk_socket_extended_layout_interface_init))
+
static void
gtk_socket_finalize (GObject *object)
static void
gtk_socket_init (GtkSocket *socket)
{
+ GtkSocketPrivate *priv;
+
socket->request_width = 0;
socket->request_height = 0;
socket->current_width = 0;
socket->accel_group = gtk_accel_group_new ();
g_object_set_data (G_OBJECT (socket->accel_group), I_("gtk-socket"), socket);
+
+ priv = _gtk_socket_get_private (socket);
+ priv->have_natural_size = FALSE;
}
/**
}
}
+static void
+gtk_socket_extended_layout_get_desired_size (GtkExtendedLayout *layout,
+ GtkRequisition *minimal_size,
+ GtkRequisition *desired_size)
+{
+ GtkSocket *socket = GTK_SOCKET (layout);
+ GtkSocketPrivate *priv;
+
+ if (socket->plug_widget)
+ {
+ gtk_extended_layout_get_desired_size (GTK_EXTENDED_LAYOUT (socket->plug_widget),
+ minimal_size,
+ desired_size);
+ }
+ else
+ {
+ priv = _gtk_socket_get_private (socket);
+
+ if (socket->is_mapped && !priv->have_natural_size && socket->plug_window)
+ {
+ _gtk_socket_windowing_size_request (socket);
+ _gtk_socket_windowing_get_natural_size (socket);
+ }
+
+ if (socket->is_mapped && priv->have_natural_size)
+ {
+ if (minimal_size)
+ {
+ minimal_size->width = MAX (socket->request_width, 1);
+ minimal_size->height = MAX (socket->request_height, 1);
+ }
+ if (desired_size)
+ {
+ desired_size->width = MAX (priv->natural_width, 1);
+ desired_size->height = MAX (priv->natural_height, 1);
+ }
+ }
+ else
+ {
+ if (minimal_size)
+ {
+ minimal_size->width = 1;
+ minimal_size->height = 1;
+ }
+ if (desired_size)
+ {
+ desired_size->width = 1;
+ desired_size->height = 1;
+ }
+ }
+ }
+}
+
+static void
+gtk_socket_extended_layout_interface_init (GtkExtendedLayoutIface *iface)
+{
+ iface->get_desired_size = gtk_socket_extended_layout_get_desired_size;
+}
+
+
#define __GTK_SOCKET_C__
#include "gtkaliasdef.c"
struct _GtkSocketPrivate
{
gint resize_count;
+ gint natural_width;
+ gint natural_height;
+ gboolean have_natural_size;
};
/* In gtksocket.c: */
*/
void _gtk_socket_windowing_size_request (GtkSocket *socket);
+void _gtk_socket_windowing_get_natural_size (GtkSocket *socket);
/*
* _gtk_socket_windowing_send_key_event:
*